package ccnt.pvc.scudwaremobile.server;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.entity.StringEntity;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpRequestHandler;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import ccnt.pvc.scudwaremobile.dao.ServiceModel;
import ccnt.pvc.scudwaremobile.service.MainService;
import ccnt.pvc.scudwaremobile.service.ScudwareServiceConnection;

import com.google.gson.Gson;

public class HttpRootHandler implements HttpRequestHandler {

	private MainService mainService;
	private final Gson gson = new Gson();
	
	public HttpRootHandler(MainService mainService) {
		this.mainService = mainService;
	}
	
	@Override
	public void handle(HttpRequest request, HttpResponse response,
			HttpContext context)
			throws HttpException, IOException {
		
		String target = URLDecoder.decode(request.getRequestLine().getUri(),
				"UTF-8");
		if(target.startsWith("/service")) {
			response.setStatusCode(HttpStatus.SC_OK);
			StringEntity entity = new StringEntity(handleService(target));
			response.setHeader("Content-Type", "text/html");
			response.setEntity(entity);
		}
		else if(target.startsWith("/device")) {
			response.setStatusCode(HttpStatus.SC_OK);
			StringEntity entity = new StringEntity(handleDevice(target));
			response.setHeader("Content-Type", "text/html");
			response.setEntity(entity);
		}
		else if(target.startsWith("/sensor")) {
			response.setStatusCode(HttpStatus.SC_OK);
			StringEntity entity = new StringEntity(handleSensor(target));
			response.setHeader("Content-Type", "text/html");
			response.setEntity(entity);
		}
		//Not Found
		else { 
			response.setStatusCode(HttpStatus.SC_NOT_FOUND);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("code", 200);
			StringEntity entity = new StringEntity(gson.toJson(params));
			response.setHeader("Content-Type", "text/html");
			response.setEntity(entity);
		}
		
	}
	
	private String handleService(String target) {
		Map<String, Object> params = new HashMap<String, Object>();
		
		if(target.equals("/service/all.json")) {
			List<ServiceModel> services = mainService.getServiceManager().getServices(null);
			params.put("code", 200);
			params.put("result", services);
			return gson.toJson(params);
		}
		
		Pattern pattern = Pattern.compile("/service/+");
		Matcher matcher = pattern.matcher(target);
		if(matcher.find()) {
			String[] temps = target.split("/");
			String className = null;
			String needed = null;
			try {
				className = temps[2];
				needed = temps[3];
			} catch(Exception e) {
				params.put("code", 404);
				params.put("result", "request error");
				return gson.toJson(params);
			}
			Map<String, ServiceModel> serviceMap = mainService.getServiceManager().getServiceMap(null);
			if(serviceMap.containsKey(className)) {
				String result = null;
				if(needed.equals("data.json")) {
					result =  invokeService(serviceMap.get(className));
				} else {
					result = gson.toJson(serviceMap.get(className));
				}
				params.put("code", 200);
				params.put("result", result);
				return gson.toJson(params);
			}
			else {
				params.put("code", 404);
				params.put("result", "service not found");
				return gson.toJson(params);
			}
		}
		return gson.toJson(params);
	}

	private String handleDevice(String target) {
		//TODO 详细的
		return null;
	}
	
	private String handleSensor(String target) {		
		//TODO 详细的
		return null;
	}
	
	private String invokeService(ServiceModel service) {
		Intent intent = new Intent();
		intent.setClassName(service.getPackageName(), service.getClassName());
		ScudwareServiceConnection conn = new ScudwareServiceConnection();
		mainService.bindService(intent, conn, Context.BIND_AUTO_CREATE);
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		String result = null;
		try {
			Bundle bundle = conn.getiDataService().getData();
			result = mainService.getBundleSerializer().serialize(bundle);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		mainService.unbindService(conn);
		return result;
	}
}
